
#include <stdlib.h>
#include <stdio.h>
#ifdef VEDA_OS_LINUX
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#endif

#include "Util.h"
#include "VInfra/VDefine.h"

namespace{

static Veda::uint16 CRC16_Table[256] = {
0x0000u, 0x1021u, 0x2042u, 0x3063u, 0x4084u, 0x50A5u, 0x60C6u, 0x70E7u,
0x8108u, 0x9129u, 0xA14Au, 0xB16Bu, 0xC18Cu, 0xD1ADu, 0xE1CEu, 0xF1EFu,
0x1231u, 0x0210u, 0x3273u, 0x2252u, 0x52B5u, 0x4294u, 0x72F7u, 0x62D6u,
0x9339u, 0x8318u, 0xB37Bu, 0xA35Au, 0xD3BDu, 0xC39Cu, 0xF3FFu, 0xE3DEu,
0x2462u, 0x3443u, 0x0420u, 0x1401u, 0x64E6u, 0x74C7u, 0x44A4u, 0x5485u,
0xA56Au, 0xB54Bu, 0x8528u, 0x9509u, 0xE5EEu, 0xF5CFu, 0xC5ACu, 0xD58Du,
0x3653u, 0x2672u, 0x1611u, 0x0630u, 0x76D7u, 0x66F6u, 0x5695u, 0x46B4u,
0xB75Bu, 0xA77Au, 0x9719u, 0x8738u, 0xF7DFu, 0xE7FEu, 0xD79Du, 0xC7BCu,
0x48C4u, 0x58E5u, 0x6886u, 0x78A7u, 0x0840u, 0x1861u, 0x2802u, 0x3823u,
0xC9CCu, 0xD9EDu, 0xE98Eu, 0xF9AFu, 0x8948u, 0x9969u, 0xA90Au, 0xB92Bu,
0x5AF5u, 0x4AD4u, 0x7AB7u, 0x6A96u, 0x1A71u, 0x0A50u, 0x3A33u, 0x2A12u,
0xDBFDu, 0xCBDCu, 0xFBBFu, 0xEB9Eu, 0x9B79u, 0x8B58u, 0xBB3Bu, 0xAB1Au,
0x6CA6u, 0x7C87u, 0x4CE4u, 0x5CC5u, 0x2C22u, 0x3C03u, 0x0C60u, 0x1C41u,
0xEDAEu, 0xFD8Fu, 0xCDECu, 0xDDCDu, 0xAD2Au, 0xBD0Bu, 0x8D68u, 0x9D49u,
0x7E97u, 0x6EB6u, 0x5ED5u, 0x4EF4u, 0x3E13u, 0x2E32u, 0x1E51u, 0x0E70u,
0xFF9Fu, 0xEFBEu, 0xDFDDu, 0xCFFCu, 0xBF1Bu, 0xAF3Au, 0x9F59u, 0x8F78u,
0x9188u, 0x81A9u, 0xB1CAu, 0xA1EBu, 0xD10Cu, 0xC12Du, 0xF14Eu, 0xE16Fu,
0x1080u, 0x00A1u, 0x30C2u, 0x20E3u, 0x5004u, 0x4025u, 0x7046u, 0x6067u,
0x83B9u, 0x9398u, 0xA3FBu, 0xB3DAu, 0xC33Du, 0xD31Cu, 0xE37Fu, 0xF35Eu,
0x02B1u, 0x1290u, 0x22F3u, 0x32D2u, 0x4235u, 0x5214u, 0x6277u, 0x7256u,
0xB5EAu, 0xA5CBu, 0x95A8u, 0x8589u, 0xF56Eu, 0xE54Fu, 0xD52Cu, 0xC50Du,
0x34E2u, 0x24C3u, 0x14A0u, 0x0481u, 0x7466u, 0x6447u, 0x5424u, 0x4405u,
0xA7DBu, 0xB7FAu, 0x8799u, 0x97B8u, 0xE75Fu, 0xF77Eu, 0xC71Du, 0xD73Cu,
0x26D3u, 0x36F2u, 0x0691u, 0x16B0u, 0x6657u, 0x7676u, 0x4615u, 0x5634u,
0xD94Cu, 0xC96Du, 0xF90Eu, 0xE92Fu, 0x99C8u, 0x89E9u, 0xB98Au, 0xA9ABu,
0x5844u, 0x4865u, 0x7806u, 0x6827u, 0x18C0u, 0x08E1u, 0x3882u, 0x28A3u,
0xCB7Du, 0xDB5Cu, 0xEB3Fu, 0xFB1Eu, 0x8BF9u, 0x9BD8u, 0xABBBu, 0xBB9Au,
0x4A75u, 0x5A54u, 0x6A37u, 0x7A16u, 0x0AF1u, 0x1AD0u, 0x2AB3u, 0x3A92u,
0xFD2Eu, 0xED0Fu, 0xDD6Cu, 0xCD4Du, 0xBDAAu, 0xAD8Bu, 0x9DE8u, 0x8DC9u,
0x7C26u, 0x6C07u, 0x5C64u, 0x4C45u, 0x3CA2u, 0x2C83u, 0x1CE0u, 0x0CC1u,
0xEF1Fu, 0xFF3Eu, 0xCF5Du, 0xDF7Cu, 0xAF9Bu, 0xBFBAu, 0x8FD9u, 0x9FF8u,
0x6E17u, 0x7E36u, 0x4E55u, 0x5E74u, 0x2E93u, 0x3EB2u, 0x0ED1u, 0x1EF0u
};

static Veda::uint32  CRC32_Table[256] =
{
0x00000000u, 0x04c11db7u, 0x09823b6eu, 0x0d4326d9u,
0x130476dcu, 0x17c56b6bu, 0x1a864db2u, 0x1e475005u,
0x2608edb8u, 0x22c9f00fu, 0x2f8ad6d6u, 0x2b4bcb61u,
0x350c9b64u, 0x31cd86d3u, 0x3c8ea00au, 0x384fbdbdu,
0x4c11db70u, 0x48d0c6c7u, 0x4593e01eu, 0x4152fda9u,
0x5f15adacu, 0x5bd4b01bu, 0x569796c2u, 0x52568b75u,
0x6a1936c8u, 0x6ed82b7fu, 0x639b0da6u, 0x675a1011u,
0x791d4014u, 0x7ddc5da3u, 0x709f7b7au, 0x745e66cdu,
0x9823b6e0u, 0x9ce2ab57u, 0x91a18d8eu, 0x95609039u,
0x8b27c03cu, 0x8fe6dd8bu, 0x82a5fb52u, 0x8664e6e5u,
0xbe2b5b58u, 0xbaea46efu, 0xb7a96036u, 0xb3687d81u,
0xad2f2d84u, 0xa9ee3033u, 0xa4ad16eau, 0xa06c0b5du,
0xd4326d90u, 0xd0f37027u, 0xddb056feu, 0xd9714b49u,
0xc7361b4cu, 0xc3f706fbu, 0xceb42022u, 0xca753d95u,
0xf23a8028u, 0xf6fb9d9fu, 0xfbb8bb46u, 0xff79a6f1u,
0xe13ef6f4u, 0xe5ffeb43u, 0xe8bccd9au, 0xec7dd02du,
0x34867077u, 0x30476dc0u, 0x3d044b19u, 0x39c556aeu,
0x278206abu, 0x23431b1cu, 0x2e003dc5u, 0x2ac12072u,
0x128e9dcfu, 0x164f8078u, 0x1b0ca6a1u, 0x1fcdbb16u,
0x018aeb13u, 0x054bf6a4u, 0x0808d07du, 0x0cc9cdcau,
0x7897ab07u, 0x7c56b6b0u, 0x71159069u, 0x75d48ddeu,
0x6b93dddbu, 0x6f52c06cu, 0x6211e6b5u, 0x66d0fb02u,
0x5e9f46bfu, 0x5a5e5b08u, 0x571d7dd1u, 0x53dc6066u,
0x4d9b3063u, 0x495a2dd4u, 0x44190b0du, 0x40d816bau,
0xaca5c697u, 0xa864db20u, 0xa527fdf9u, 0xa1e6e04eu,
0xbfa1b04bu, 0xbb60adfcu, 0xb6238b25u, 0xb2e29692u,
0x8aad2b2fu, 0x8e6c3698u, 0x832f1041u, 0x87ee0df6u,
0x99a95df3u, 0x9d684044u, 0x902b669du, 0x94ea7b2au,
0xe0b41de7u, 0xe4750050u, 0xe9362689u, 0xedf73b3eu,
0xf3b06b3bu, 0xf771768cu, 0xfa325055u, 0xfef34de2u,
0xc6bcf05fu, 0xc27dede8u, 0xcf3ecb31u, 0xcbffd686u,
0xd5b88683u, 0xd1799b34u, 0xdc3abdedu, 0xd8fba05au,
0x690ce0eeu, 0x6dcdfd59u, 0x608edb80u, 0x644fc637u,
0x7a089632u, 0x7ec98b85u, 0x738aad5cu, 0x774bb0ebu,
0x4f040d56u, 0x4bc510e1u, 0x46863638u, 0x42472b8fu,
0x5c007b8au, 0x58c1663du, 0x558240e4u, 0x51435d53u,
0x251d3b9eu, 0x21dc2629u, 0x2c9f00f0u, 0x285e1d47u,
0x36194d42u, 0x32d850f5u, 0x3f9b762cu, 0x3b5a6b9bu,
0x0315d626u, 0x07d4cb91u, 0x0a97ed48u, 0x0e56f0ffu,
0x1011a0fau, 0x14d0bd4du, 0x19939b94u, 0x1d528623u,
0xf12f560eu, 0xf5ee4bb9u, 0xf8ad6d60u, 0xfc6c70d7u,
0xe22b20d2u, 0xe6ea3d65u, 0xeba91bbcu, 0xef68060bu,
0xd727bbb6u, 0xd3e6a601u, 0xdea580d8u, 0xda649d6fu,
0xc423cd6au, 0xc0e2d0ddu, 0xcda1f604u, 0xc960ebb3u,
0xbd3e8d7eu, 0xb9ff90c9u, 0xb4bcb610u, 0xb07daba7u,
0xae3afba2u, 0xaafbe615u, 0xa7b8c0ccu, 0xa379dd7bu,
0x9b3660c6u, 0x9ff77d71u, 0x92b45ba8u, 0x9675461fu,
0x8832161au, 0x8cf30badu, 0x81b02d74u, 0x857130c3u,
0x5d8a9099u, 0x594b8d2eu, 0x5408abf7u, 0x50c9b640u,
0x4e8ee645u, 0x4a4ffbf2u, 0x470cdd2bu, 0x43cdc09cu,
0x7b827d21u, 0x7f436096u, 0x7200464fu, 0x76c15bf8u,
0x68860bfdu, 0x6c47164au, 0x61043093u, 0x65c52d24u,
0x119b4be9u, 0x155a565eu, 0x18197087u, 0x1cd86d30u,
0x029f3d35u, 0x065e2082u, 0x0b1d065bu, 0x0fdc1becu,
0x3793a651u, 0x3352bbe6u, 0x3e119d3fu, 0x3ad08088u,
0x2497d08du, 0x2056cd3au, 0x2d15ebe3u, 0x29d4f654u,
0xc5a92679u, 0xc1683bceu, 0xcc2b1d17u, 0xc8ea00a0u,
0xd6ad50a5u, 0xd26c4d12u, 0xdf2f6bcbu, 0xdbee767cu,
0xe3a1cbc1u, 0xe760d676u, 0xea23f0afu, 0xeee2ed18u,
0xf0a5bd1du, 0xf464a0aau, 0xf9278673u, 0xfde69bc4u,
0x89b8fd09u, 0x8d79e0beu, 0x803ac667u, 0x84fbdbd0u,
0x9abc8bd5u, 0x9e7d9662u, 0x933eb0bbu, 0x97ffad0cu,
0xafb010b1u, 0xab710d06u, 0xa6322bdfu, 0xa2f33668u,
0xbcb4666du, 0xb8757bdau, 0xb5365d03u, 0xb1f740b4u
};

}

namespace Veda{

int Vsyscall(const char* cmd)
{
	if(cmd == NULL)
	{
		return 1;
	}
	int ret = -1;

#ifdef VEDA_OS_LINUX
	pid_t pid = vfork();
	if(pid < 0)
	{
		printf("Vsyscall failed!\n");
	}
	else if(pid == 0)
	{
		//printf("in child: ppid=%d, pid=%d\n", getppid(), getpid());
		execl("/bin/sh", "sh", "-c", cmd, (char*)0);
		_exit(127);
	}
	else
	{
		//printf("in parent: pid=%d\n", getpid());
		while(waitpid(pid, &ret, 0) < 0)
		{
			if(errno != EINTR)
			{
				ret = -1;
				break;
			}
		}
	}
#endif
	return ret;
}

int Vlog2i(uint32 x)
{
	int r = 31;

	if(!x)
	{
		return 1/x;
	}
	if(!(x & 0xffff0000u))
	{
		x <<= 16;
		r -= 16;
	}
	if(!(x & 0xff000000u))
	{
		x <<= 8;
		r -= 8;
	}
	if(!(x & 0xf0000000u))
	{
		x <<= 4;
		r -= 4;
	}
	if(!(x & 0xc0000000u))
	{
		x <<= 2;
		r -= 2;
	}
	if(!(x & 0x80000000u))
	{
		x <<= 1;
		r -= 1;
	}
	return r;
}

void VprintByte(uint32 x)
{
	int n = sizeof(uint32)*8;
	uint32 mask = 1 << (n-1);
	for(int i=1; i<=n; i++)
	{
		printf("%c", (((x & mask) == 0)?'0':'1'));
		x <<= 1;
		if( i%8 == 0 && i<n)
			printf(" ");
	}
	printf("\n");
}

uint16 VgetCRC16(uchar* data, uint32 len)
{
	uint16 crc = 0;
	while (len-- > 0)
	{
		crc = CRC16_Table[((crc >> 8 ^ *data++) & 0xff)] ^ (uint16)(crc << 8);
	}
	return (uint16)~crc;
}

uint32 VgetCRC32(uchar* data, uint32 len)
{
	uint32 crc = 0;
	while(len-- > 0)
	{
		crc = CRC32_Table[((crc >> 24 ) ^ *data++)] ^ ( crc << 8 );
	}
	return crc;
}


}

